package com.ibm.spatiotemp.processor;

import java.io.IOException;
import java.util.Collection;

import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;

import com.ibm.spatiotemp.datamodel.result.SpatialResultCollector;
import com.ibm.spatiotemp.datamodel.result.SpatialResultCollector2;
import com.ibm.spatiotemp.datamodel.result.SpatioObjectResultSet;
import com.ibm.spatiotemp.datamodel.result.SpatialResultCollector2.KNNEntry;
import com.ibm.spatiotemp.index.GeoIndexDBManager;

import edu.umn.cs.spatialHadoop.core.Point;
import edu.umn.cs.spatialHadoop.core.RTreeLocal;
import edu.umn.cs.spatialHadoop.core.Shape;

public class RtreeSearcher2<T extends Shape> implements SpatialSearcher {

	protected RTreeLocal<T>  RtreeObject;
	FSDataInputStream fs_instream;
	String rtreepath_path_str;
	T object_reflector;
	FileSystem fs;
	SpatialResultCollector<T> result_collector;
	SpatialResultCollector2<T, KNNEntry<T,Double>> result_collector2;
	protected boolean ld_tocache = false;
	
//	public boolean isLd_tomem() {
//		return ld_tocache;
//	}


//	public void setLd_tomem(boolean ld_tomem) {
//		this.ld_tocache = ld_tomem;
//	}

	public RtreeSearcher2(String rtree_path, T ref, boolean Ltocache) throws Exception
	{
		this.rtreepath_path_str = rtree_path;
		this.object_reflector = ref;
		
		result_collector = new SpatialResultCollector<T>();
		result_collector2 = new SpatialResultCollector2<T, KNNEntry<T,Double>>();
		ld_tocache = Ltocache;
		LoadSpatialObjects();
	}
	
	@Override
	public void LoadSpatialObjects() throws Exception {
		if(RtreeObject == null)
			RtreeObject = new RTreeLocal<T>(object_reflector,rtreepath_path_str);
		RtreeObject.loadRTreetoLocal(GeoIndexDBManager.
				getRtreeDataInputStream(rtreepath_path_str,ld_tocache));
        }
	
	@Override
	public SpatioObjectResultSet Range_Query(Shape queryshape) throws Exception {
		RtreeObject.search(queryshape, result_collector);
		return new SpatioObjectResultSet(result_collector);
	}

	@Override
	public SpatioObjectResultSet KNN_Query(Point querypoint, int k) throws Exception {
		RtreeObject.knn(querypoint.getMBR().x1, querypoint.getMBR().y1, k, result_collector2);
		return new SpatioObjectResultSet(result_collector2);
	}

	@Override
	public SpatioObjectResultSet spatialJoin(Collection<Shape> collection1,
			Collection<Shape> collition2) {
		return null;
	}


	@Override
	public void close() {
		try {
			if(fs_instream !=null)
				fs_instream.close();
			if(fs != null)
				fs.close();
			
			fs_instream = null;
			fs = null;
		} catch (IOException e) {
		}
		
	}
	
	

}
